package net.skyaims.aiolia.chat.core;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public abstract class Platform<Opt extends Option, Env extends Environment> implements
        LifeCycle<Opt, Env>, Runnable {

    private static final Logger log = LoggerFactory.getLogger(Platform.class);

    private final String instanceName;
    private final String optionFile;

    public String getOptionFile() {
        return optionFile;
    }

    public String getInstanceName() {
        return instanceName;
    }

    private Opt opt;
    private Env env;

    public Env getEnv() {
        return env;
    }

    public void setEnv(Env env) {
        this.env = env;
    }

    public Opt getOpt() {
        return opt;
    }

    public void setOpt(Opt opt) {
        this.opt = opt;
    }

    public Platform(String instanceName, String optionFile) {
        this.instanceName = instanceName;
        this.optionFile = optionFile;
    }

    @Override
    public void run() {
        try {
            log.info("{} Server Instance Begin Service", this.instanceName);
            Opt opt = loadOpt(getOptionFile());
            Env env = loadEnv(getInstanceName());
            startup(opt);
            initialize(env);
            service(opt, env);
            Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        Platform.this.shutdown();
                        log.info("{} Server Instance Stop Service", Platform.this.getInstanceName());
                    } catch (Exception e) {
                        log.error(" Server Instance Shutdown Exception", Platform.this.getInstanceName());
                        log.error(e.getMessage(), e);
                    }
                }
            }));
        } catch (Exception e) {
            log.error("{} Server Instance Runtime Exception", this.instanceName);
            log.error(e.getMessage(), e);
        }
    }

    public abstract void service(Opt opt, Env env) throws Exception;

    protected abstract Opt loadOpt(String optionFile);

    protected abstract Env loadEnv(String instanceName);

}
